package com.smart.community.device.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smart.community.device.entity.Device;
import com.smart.community.device.mapper.DeviceMapper;
import com.smart.community.device.service.IDeviceService;
import com.smart.community.device.vo.DeviceVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 设备管理服务实现类
 * @author Wu.Liang
 * @since 2024-12-21
 */
@Service
@Slf4j
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements IDeviceService {
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createDevice(Device device) {
        log.info("创建设备，设备信息：{}", device);
        device.setCreateTime(LocalDateTime.now());
        return this.save(device);
    }
    
    @Override
    public IPage<DeviceVO> getDevicePage(Integer current, Integer size, String deviceName, 
                                        Integer deviceType, Integer deviceStatus, Long communityId) {
        log.info("分页查询设备列表，当前页：{}，每页大小：{}", current, size);
        
        Page<Device> page = new Page<>(current, size);
        LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Device::getDeleted, 0);
        
        if (StringUtils.hasText(deviceName)) {
            queryWrapper.like(Device::getDeviceName, deviceName);
        }
        if (deviceType != null) {
            queryWrapper.eq(Device::getDeviceType, deviceType);
        }
        if (deviceStatus != null) {
            queryWrapper.eq(Device::getDeviceStatus, deviceStatus);
        }
        if (communityId != null) {
            queryWrapper.eq(Device::getCommunityId, communityId);
        }
        
        queryWrapper.orderByDesc(Device::getCreateTime);
        
        IPage<Device> devicePage = this.page(page, queryWrapper);
        List<DeviceVO> voList = devicePage.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
        
        Page<DeviceVO> voPage = new Page<>(current, size);
        voPage.setRecords(voList);
        voPage.setTotal(devicePage.getTotal());
        voPage.setCurrent(devicePage.getCurrent());
        voPage.setSize(devicePage.getSize());
        
        return voPage;
    }
    
    @Override
    public List<DeviceVO> getDevicesByCommunityIds(List<Long> communityIds, Integer deviceType, Integer deviceStatus) {
        log.info("根据社区ID集合查询设备，社区ID：{}，类型：{}，状态：{}", communityIds, deviceType, deviceStatus);
        
        LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Device::getDeleted, 0);
        queryWrapper.in(Device::getCommunityId, communityIds);
        
        if (deviceType != null) {
            queryWrapper.eq(Device::getDeviceType, deviceType);
        }
        if (deviceStatus != null) {
            queryWrapper.eq(Device::getDeviceStatus, deviceStatus);
        }
        
        queryWrapper.orderByAsc(Device::getDeviceType).orderByAsc(Device::getDeviceName);
        
        List<Device> deviceList = this.list(queryWrapper);
        return deviceList.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }
    
    @Override
    public Map<Integer, List<DeviceVO>> getDevicesGroupedByType(List<Long> communityIds, Integer deviceStatus) {
        log.info("根据社区ID集合查询设备并按类型分组，社区ID：{}，状态：{}", communityIds, deviceStatus);
        
        List<DeviceVO> deviceVOList = getDevicesByCommunityIds(communityIds, null, deviceStatus);
        Map<Integer, List<DeviceVO>> grouped = new HashMap<>();
        
        for (DeviceVO vo : deviceVOList) {
            Integer deviceType = vo.getDeviceType();
            grouped.computeIfAbsent(deviceType, k -> new java.util.ArrayList<>()).add(vo);
        }
        
        return grouped;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDevice(Device device) {
        log.info("更新设备，设备信息：{}", device);
        device.setUpdateTime(LocalDateTime.now());
        return this.updateById(device);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDeviceStatus(Long deviceId, Integer deviceStatus) {
        log.info("更新设备状态，设备ID：{}，状态：{}", deviceId, deviceStatus);
        
        Device device = new Device();
        device.setId(deviceId);
        device.setDeviceStatus(deviceStatus);
        device.setUpdateTime(LocalDateTime.now());
        
        return this.updateById(device);
    }
    
    @Override
    public Object getDeviceStatistics(Long communityId) {
        log.info("获取设备统计信息，社区ID：{}", communityId);
        
        LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Device::getDeleted, 0);
        if (communityId != null) {
            queryWrapper.eq(Device::getCommunityId, communityId);
        }
        
        List<Device> deviceList = this.list(queryWrapper);
        
        Map<String, Object> statistics = new HashMap<>();
        statistics.put("totalCount", deviceList.size());
        statistics.put("onlineCount", (int) deviceList.stream().filter(d -> d.getDeviceStatus() == 1).count());
        statistics.put("offlineCount", (int) deviceList.stream().filter(d -> d.getDeviceStatus() == 0).count());
        statistics.put("faultCount", (int) deviceList.stream().filter(d -> d.getDeviceStatus() == 2).count());
        statistics.put("maintenanceCount", (int) deviceList.stream().filter(d -> d.getDeviceStatus() == 3).count());
        
        // 按类型统计
        Map<Integer, Long> typeStatistics = deviceList.stream()
                .collect(Collectors.groupingBy(Device::getDeviceType, Collectors.counting()));
        statistics.put("typeStatistics", typeStatistics);
        
        return statistics;
    }
    
    @Override
    public DeviceVO getDeviceDetail(Long deviceId) {
        log.info("获取设备详情，设备ID：{}", deviceId);
        
        LambdaQueryWrapper<Device> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Device::getId, deviceId);
        queryWrapper.eq(Device::getDeleted, 0);
        
        Device device = this.getOne(queryWrapper);
        if (device == null) {
            return null;
        }
        
        return convertToVO(device);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateDeviceStatus(List<Long> deviceIds, Integer deviceStatus) {
        log.info("批量更新设备状态，设备ID列表：{}，状态：{}", deviceIds, deviceStatus);
        
        List<Device> deviceList = this.listByIds(deviceIds);
        for (Device device : deviceList) {
            device.setDeviceStatus(deviceStatus);
            device.setUpdateTime(LocalDateTime.now());
        }
        
        return this.updateBatchById(deviceList);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteDevice(Long deviceId) {
        log.info("删除设备，设备ID：{}", deviceId);
        
        Device device = new Device();
        device.setId(deviceId);
        device.setDeleted(1);
        device.setUpdateTime(LocalDateTime.now());
        
        return this.updateById(device);
    }
    
    /**
     * 转换为VO
     */
    private DeviceVO convertToVO(Device device) {
        DeviceVO vo = new DeviceVO();
        BeanUtils.copyProperties(device, vo);
        vo.setDeviceTypeDesc(device.getTypeDesc());
        vo.setDeviceStatusDesc(device.getStatusDesc());
        return vo;
    }
}
